home *** CD-ROM | disk | FTP | other *** search
/ PC Open 92 / PC Open 92 CD 2.bin / Demo / finereader 7 pro TRIAL / FR70pro_en_it.exe / Data1.cab / pdf_font.ps < prev    next >
Encoding:
Text File  |  2002-10-23  |  40.0 KB  |  1,268 lines

  1. %    Copyright (C) 1994-2002 artofcode LLC.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: pdf_font.ps,v 1.23.2.6 2002/04/16 06:11:29 giles Exp $
  14. % pdf_font.ps
  15. % PDF font operations.
  16.  
  17. % ATAPY changes at 23.10.2002. Comments about changes started with string "(ATAPY changes)"
  18.  
  19. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  20. .currentglobal true .setglobal
  21. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  22. GS_PDF_ProcSet begin
  23. pdfdict begin
  24.  
  25. % We cache the PostScript font in an additional element of the
  26. % font resource dictionary, called PSFont.
  27.  
  28. % ---------------- Encodings ---------------- %
  29.  
  30. % Apply a list of differences to an Encoding.
  31. % Note that the differences may cause the array to grow.
  32. /updateencoding {    % <encoding> <differences> updateencoding <enc'>
  33.     % Calculate the length of the result.
  34.   exch 0 2 index {
  35.     dup type /nametype ne { exch pop } { pop 1 add } ifelse
  36.   } forall
  37.   1 index length .max array dup 0 4 -1 roll putinterval
  38.   exch 0 exch {
  39.         % Stack: enc' code element
  40.     dup type /nametype ne
  41.       { exch pop }
  42.       { 3 copy put pop 1 add }
  43.     ifelse
  44.   } forall pop
  45. } bdef
  46.  
  47. % Get the Encoding for a font.
  48. /getencoding        % <base-encoding> <font-resource> getencoding <enc>
  49.  { /Encoding knownoget
  50.     { dup type /nametype eq
  51.        { 
  52.          % The published PDF specification says the Encoding name
  53.          % "must be" one of the 3 predefined Encodings, implying
  54.          % that an error should occur if it isn't.  However, Acrobat
  55.          % Reader simply ignores unknown names, and since there are
  56.          % some buggy applications that rely on this, we do the same.
  57.  
  58.          dup dup dup /MacRomanEncoding eq
  59.          exch /MacExpertEncoding eq or 
  60.          exch /WinAnsiEncoding eq or
  61.            { exch pop findencoding
  62.            }
  63.            { pop
  64.            }
  65.          ifelse
  66.        }
  67.        { dup /BaseEncoding knownoget
  68.       { findencoding 3 -1 roll pop exch
  69.       }
  70.      if
  71.      /Differences knownoget { updateencoding } if
  72.        }
  73.       ifelse
  74.     }
  75.    if
  76.  } bdef
  77.  
  78. % Rename a font with a generated name.
  79. /renamefont {        % <fontdict> renamefont <font'>
  80.   dup /FontName 2 copy get genfontname dup 5 1 roll put definefont
  81. } bind def
  82.  
  83. % Adjust a font according to the Encoding and Widths in the font resource.
  84. /adjustfont {        % <font-resource> <font> adjustfont <font'>
  85.   getfontencoding
  86.   getfontmetrics 4 -1 roll pop .updatefont { renamefont } if
  87. } bind def
  88.  
  89. % Get the (possibly modified) encoding of a font.
  90. /getfontencoding {    % <font-resource> <font> getfontencoding
  91.             %   <font-resource> <font> <Encoding|null>
  92.   1 index /Encoding known {
  93.     dup /Encoding .knownget { 2 index getencoding } { null } ifelse
  94.   } {
  95.     null
  96.   } ifelse
  97. } bdef
  98.  
  99. /find_in_diff     % <Differences> <index> find_in_diff <bool>
  100. { false exch 0 4 3 roll
  101.   { dup type /nametype ne { exch pop } { pop 1 add } ifelse
  102.     2 copy eq {
  103.       pop pop pop true 0 0 exit
  104.     } if
  105.   } forall
  106.   pop pop
  107. } bdef
  108.  
  109. % Get the metrics of a font, if specified.
  110. /getfontmetrics {    % <font-resource> <font> <Encoding|null> getfontmetrics
  111.             %   <font-resource> <font> <Encoding|null>
  112.             %   <Metrics|null>
  113.   2 index /Widths known {
  114.     dup null eq { pop dup /Encoding get } if
  115.     4 dict begin
  116.       /Encoding exch def
  117.       /Metrics Encoding length dict def
  118.       exch
  119.       dup /Widths oget /Widths exch def
  120.         % Stack: font font-res
  121.         % Note that widths are always based on a 1000-unit
  122.         % character space, but the FontMatrix may specify
  123.         % some other scale factor.  Compensate for this here,
  124.         % by scaling the Widths if necessary.
  125.       0.001 2 index /FontMatrix get 0 get div
  126.         % Stack: font font-res mscale
  127.       1 index /FirstChar oget dup 1 4 index /LastChar oget
  128.        {    % Stack: font font-res mscale first-char index
  129.      Encoding 1 index get
  130.      Widths 2 index 4 index sub oget
  131.          % Stack: font font-res mscale first-char index charname width
  132.      4 index mul
  133.         % The following 'loop' is only context for 'exit'.
  134.      {    
  135.         % Work around a bug in pdfTeX, which can generate Encoding
  136.         % vectors containing nulls :
  137.        1 index null eq { exit } if
  138.         % There is a hack here to deal with encodings where the
  139.         % same character appears more than once, because the Metrics
  140.         % dictionary works by character name, not by character code.
  141.         % We prefer to take (1) non-zero width, and (2) width for 
  142.         % the character code which appears in Differences.
  143.        Metrics 2 index .knownget not { 0 } if 0 ne {
  144.          5 index /Encoding knownoget not { exit } if
  145.          dup type /dicttype ne { pop exit } if
  146.          /Differences knownoget not { exit } if
  147.          3 index //find_in_diff exec not { exit } if
  148.        } if
  149.        2 copy Metrics 3 1 roll put
  150.        exit
  151.      } loop
  152.      pop pop pop
  153.        }
  154.       for pop
  155.         % Now fill in the MissingWidth for any encoded characters
  156.         % that aren't in Metrics already.  Note that built-in
  157.         % fonts may have Widths/FirstChar/LastChar but no
  158.         % FontDescriptor, so we must check for this.
  159.         % Stack: font font-res mscale
  160.       1 index /FontDescriptor knownoget {
  161.     Metrics exch
  162.     /MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
  163.     Encoding {
  164.         % Stack: font font-res mscale missing-width metrics charname
  165.         % Work around the abovementioned pdfTeX bug.
  166.       dup null ne {
  167.         2 copy known not { 2 copy 4 index put } if pop
  168.       } {
  169.         pop
  170.       } ifelse
  171.     } forall pop pop pop
  172.       } {
  173.     pop
  174.       } ifelse
  175.     exch Encoding Metrics end
  176.   } {
  177.     null
  178.   } ifelse
  179. } bdef
  180.  
  181. currentdict /find_in_diff undef
  182.  
  183. % ---------------- Descriptors ---------------- %
  184.  
  185. % Partial descriptors for the 14 built-in fonts.  Note that
  186. % from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor
  187. % object has undergone a subtle change in its meaning which has serious
  188. % consequences for searching with Acrobat:
  189. % In PDF 1.1, the flag meant: Font has StandardEncoding
  190. % In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet
  191. /standardfontdescriptors mark
  192.   /Courier mark /Flags 16#23 .dicttomark
  193.   /Courier-Oblique 1 index
  194.   /Courier-Bold 1 index
  195.   /Courier-BoldOblique 1 index
  196.   /Helvetica mark /Flags 16#20 .dicttomark
  197.   /Helvetica-Oblique 1 index
  198.   /Helvetica-Bold 1 index
  199.   /Helvetica-BoldOblique 1 index
  200.   /Times-Roman mark /Flags 16#22 .dicttomark
  201.   /Times-Bold 1 index
  202.   /Times-Italic mark /Flags 16#62 .dicttomark
  203.   /Times-BoldItalic 1 index
  204.   /Symbol mark /Flags 16#4 .dicttomark
  205.   /ZapfDingbats 1 index
  206. .dicttomark readonly def
  207.  
  208. % ---------------- Utilities ---------------- %
  209.  
  210. /.glyphpath {    % <glyphname> <boolean> .glyphpath -
  211.   % another glyphpath written in addxchar.ps does not work here...
  212.   currentfont 3 1 roll exch
  213.   currentfont dup length dict begin
  214.     { 1 index /Encoding eq { pop [ 3 -1 roll ] def } { def } ifelse } forall
  215.   currentdict end /.glyphpathfont exch definefont
  216.   setfont <00> exch charpath setfont
  217. } bdef
  218.  
  219. /makeboldfont {    % <basefont> <strokewidth> makeboldfont <boldfont>
  220.   10 dict begin
  221.     /strokewidth exch def
  222.     /basefont exch def
  223.     /FontMatrix matrix def
  224.     %/FontName basefont /FontName get def
  225.     /FontName /.boldfont def
  226.     /FontType 3 def
  227.     /Encoding basefont /Encoding get def
  228.     /FontBBox [ basefont /FontBBox get cvx exec
  229.       4 2 roll basefont /FontMatrix get transform
  230.       4 2 roll basefont /FontMatrix get transform
  231.     ] def
  232.     /BuildGlyph {
  233.       gsave
  234.       exch begin
  235.         basefont setfont
  236.         strokewidth setlinewidth
  237.         1 setlinejoin
  238.         newpath
  239.         0 0 moveto dup false .glyphpath stroke
  240.         0 0 moveto glyphshow
  241.         currentpoint setcharwidth
  242.       end
  243.       grestore
  244.     } bind def
  245.    currentdict
  246.   end
  247.   dup /FontName get exch definefont
  248. } bind def
  249.  
  250. % Fabricate a font name by adding ?'s on the end.
  251. /genfontname        % <name> genfontname <name>
  252.  { dup length string cvs
  253.     { (?) concatstrings
  254.       dup cvn FontDirectory exch known not { cvn exit } if
  255.     }
  256.    loop
  257.  } bdef
  258.  
  259. % Find a font, and adjust its encoding if necessary.
  260. /.pdfdfndict mark
  261.   /defaultfontname /Helvetica
  262. .dicttomark readonly def
  263.  
  264. % (ATAPY changes) 
  265. /calcAverageCharWidth { % [width_array] calcAverageCharWidth averageWidth
  266.     dup 0 exch { 
  267.         add
  268.     } forall exch % calc sum
  269.     0 exch { 
  270.         0 ne { 1 add } if 
  271.     } forall dup 0 eq { exch pop } { div } ifelse % sum / ( positive size )
  272. } bdef
  273. % (end of ATAPY changes) 
  274.  
  275. /pdffindfont {        % <font-resource> <fontname> pdffindfont <font>
  276.         % If the font isn't available, synthesize one based on
  277.         % its descriptor.
  278.   dup /Font resourcestatus {
  279.     pop pop findfont
  280.   } {
  281.     1 index /FontDescriptor knownoget {
  282.         % Stack: font-res fontname fontdesc
  283.       dup /Flags oget
  284.       dup 16#40 and -6 bitshift        % 1, oblique/italic
  285.       1 index 16#40000 and -17 bitshift add    % 2, bold
  286.         % (ATAPY changes) actually Adobe PDF documentation says "force bold on small size"
  287.       exch 16#2 and 2 bitshift add    % 8, serif
  288.         % We should look at the fixed flag, too.
  289.         % Stack: font-res fontname fontdesc properties
  290.       1 index /FontName oget exch
  291.         % Analyzes font name and extract "Narrow" property
  292.         % which is not described by the FontDescriptor Flags.
  293.  
  294.         % (ATAPY changes) We also extract "Bold" property, 4 -> 6 in the next line:
  295.       0 2 index .fontnameproperties 6 and or
  296.  
  297.         % (ATAPY changes) Some PDF-s contain no "Italic" flag in /Flags, but have negative /ItalicAngle
  298.         dup 1 and 0 eq {
  299.             % Stack: font-res fontname fontdesc fontname properties
  300.             2 index /ItalicAngle oget 0 lt {
  301.                 (Negative /ItalicAngle with no italic flag, force italic...\n) print
  302.                 1 or
  303.             } if
  304.         } if
  305.  
  306.         % (ATAPY changes) Try to analyze width table for narrow font
  307.         % Stack: font-res fontname fontdesc fontname properties
  308.         
  309.         4 index /Widths get calcAverageCharWidth (Avarage char width = ) print dup ==
  310.         
  311.         % Then if width is too small and font is sanserif turn on "Narrow" flag
  312.  
  313.         [510 530 540 550] % predefined average widths for Helvetica [normal it bold bold-it]
  314.         2 index 3 and get % extract bold and italic properties to get corresponding width
  315.         (Base font char width = ) print dup ==
  316.         le { dup 8 and 0 eq { 
  317.                 4 or (Too narrow font, try turn on "Narrow" flag...\n) print 
  318.             } if 
  319.         } if
  320.         
  321.         % (ATAPY changes) End of changes
  322.  
  323.         % Rebind the default font name to Helvetica so that
  324.         % fonts with no properties are handled correctly.
  325.       //.pdfdfndict begin .substitutefontname end
  326.         % Stack: font-res fontname fontdesc substname|null
  327.       Fontmap 1 index known not {
  328.         % No available good substitution, use the standard one.
  329.     pop 1 index .substitutefont
  330.       } if
  331.       QUIET not {
  332.     (Substituting font ) print dup =only
  333.     ( for ) print 2 index =only (.) = flush
  334.       } if
  335.       3 -1 roll pop findfont
  336.         % Stack: font-res fontdesc font
  337.         % If this is a small-caps font, replace the CharString
  338.         % entries for a..z.
  339.       exch /Flags oget 16#20000 and 0 ne {
  340.     true .copyfontdict
  341.     dup /CharStrings 2 copy get dup length dict .copydict
  342.     4 index /FirstChar get 97 .max
  343.     5 index /LastChar get 122 .min 1 exch {
  344.         % Stack: font-res font' font' /CharStrings charstrings code
  345.         % Note that this only remaps a-z, not accented characters.
  346.       5 index /Widths oget 1 index 7 index /FirstChar get sub oget
  347.       1 string dup 0 5 -1 roll put
  348.         % Stack: font-res font' font' /CharStrings charstrings code
  349.         %   width (x)
  350.       2 index exch dup cvn exch
  351.       dup 0 2 copy get 32 sub put 4 -1 roll {
  352.             % Stack: operand (X) width
  353.         0 setcharwidth exch pop
  354.         currentfont /FontMatrix get matrix invertmatrix concat
  355.         0.7 dup scale 0 0 moveto show
  356.       } /exec cvx 4 packedarray cvx put
  357.     } for put
  358.     renamefont
  359.       } if
  360.     } {
  361.         % No descriptor available, use the default algorithm.
  362.       findfont
  363.     } ifelse
  364.   } ifelse adjustfont
  365. } bdef
  366. /findpdffont {    % <font-resource> <fontname> findpdffont <font>
  367.   {} 3 1 roll            % proc fnres fnname
  368.   [
  369.     [ (,Bold)        { .03 makeboldfont } ]
  370.     [ (,BoldItalic)    { .03 makeboldfont [ 1 0 .3 1 0 0 ] makefont } bind ]
  371.     [ (,Italic)        { [ 1 0 .3 1 0 0 ] makefont } bind ]
  372.   ] {
  373.     1 index dup length string cvs
  374.     1 index 0 get tailmatch {    % proc fnres fnname []
  375.       3 -1 roll pop exch 1 get    % proc fnres pre-fnname proc
  376.       4 -1 roll pop 3 1 roll    % proc fnres pre-fnname
  377.       exit
  378.     } { pop pop } ifelse     % proc fnres fnname
  379.   } forall
  380.   pdffindfont exch exec
  381. } bdef
  382.  
  383. % ---------------- Type 1 fonts ---------------- %
  384.  
  385. /buildType1        % <Type1-font-resource> buildType1 <font>
  386.  { dup /BaseFont get pdffindfont
  387.  } bdef
  388.  
  389. % The state dictionary for the embedded Type 1 font reading procedure
  390. % has the following keys and values:
  391. %    data - stream (filter)
  392. %    buffer, buffer2 - string
  393. %    hexify - procedure to convert buffer to hex if needed
  394. %    leftstr - string containing (non-negative) integer
  395. %    sectionstr - string containing a character 0 .. 3
  396. %    stream - (stream) dictionary
  397. %    proc - procedure of the form {-dict- type1read}
  398. %       pfbhdr - string containing 16#80 if PFB, 0 otherwise
  399. % When the procedure is executing, this dictionary is current.
  400. % leftstr and sectionstr are strings so that we can change their values
  401. % reliably in case the font executes a restore!
  402. % We also have to do something special about embedded fonts that
  403. % execute definefont more than once -- that is the function of topFontDict.
  404.  
  405. % Read an embedded Type 1 font.
  406. /readfontfilter {    % <proc> readfontfilter <filter>
  407.   0 () /SubFileDecode filter
  408. } bdef
  409. /readtype1dict 5 dict dup begin
  410.   /definefont {
  411.     dup topFontDict eq topFontDict null eq or {
  412.       dup wcheck not { dup length dict copy } if
  413.       exch pop savedFontName exch
  414.     } if
  415.     //systemdict /definefont get exec
  416.   } bdef
  417.   /eexec {
  418.     % Assume the font dictionary is directly below the file on the stack
  419.     count 0 gt { /topFontDict 2 index cvlit store } if
  420.     55665 /eexecDecode filter
  421.     //systemdict begin readtype1dictcopy begin cvx stopped
  422.     currentdict readtype1dictcopy eq { end } if
  423.     currentdict //systemdict eq { end } if
  424.      { stop } if
  425.   } bdef
  426. end readonly def
  427. /readtype1 {        % <font-resource> <stream-dict> readtype1 <font>
  428.         % Read the definition, using a procedure-based filter
  429.         % that turns binary/hex conversion on and off
  430.         % at the right times.
  431.    1 index exch
  432.    PDFfile fileposition 3 1 roll
  433.    11 dict begin
  434.      /leftstr (          ) 10 string copy def
  435.        dup /Length1 oget leftstr cvs pop
  436.      /sectionstr <00> 1 string copy def
  437.      /pfbhdr <00> 1 string copy def
  438.      /stream 1 index def
  439.      true resolvestream /data exch def
  440.      /buffer 1000 string def        % arbitrary
  441.      /buffer2 buffer length 2.1 div cvi 1 sub string def
  442.      /hexify /buf2hex load def
  443.    currentdict end
  444.    /type1read cvx 2 array astore cvx dup 0 get /proc 2 index put
  445.    readfontfilter
  446.         % Some buggy embedded fonts leave extra junk on the stack,
  447.         % so we have to make a closure that records the stack depth
  448.         % in a fail-safe way.
  449.    //systemdict begin
  450.         % The PDF specification is somewhat muddy about whether
  451.         % an embedded font's name is supposed to be the BaseFont
  452.         % from the Font object or the FontName from the descriptor.
  453.         % Acrobat Distiller requires the former.  Save away the
  454.         % name so we can substitute it at definefont time.
  455.    //readtype1dict dup length 3 add dict copy begin
  456.    1 index /BaseFont oget /savedFontName exch def
  457.    /topFontDict null def
  458.    /readtype1dictcopy currentdict def
  459.     { run } aload pop count 1 sub 2 packedarray cvx exec
  460.    end end
  461.    count exch sub { pop } repeat
  462.    PDFfile 3 -1 roll setfileposition
  463.    /BaseFont oget findfont
  464.    adjustfont
  465.  } bdef
  466.  
  467. % Execute the appropriate reading procedure.
  468. /type1read        % <dict> type1read <string>
  469.  { begin leftstr cvi
  470.     { type1read0 type1read1 type1read2 type1read3 } sectionstr 0 get get exec
  471.    (          ) leftstr copy cvs pop end
  472.  } bdef
  473.  
  474. % Read the next block of data into the buffer.
  475. /type1readdata        % <left> <buffer> type1readdata <substring> <left'>
  476.  { 0 2 index 2 index length .min getinterval
  477.         % Adobe requires readstring to signal an error if given
  478.         % an empty string.  Work around this nonsense here.
  479.    dup length 0 ne { data exch readstring pop } if
  480.    dup length 3 -1 roll exch sub
  481.    DEBUG
  482.     { dup =only ( read ) print
  483.       1 index length =only (: ) print
  484.       1 index == flush
  485.     } if
  486.  } bdef
  487.  
  488. % Read the initial byte to see if we need to skip a 6 byte PFB header
  489. /type1read0 {         % <left> type1read0 <string> <left'>
  490.   sectionstr 0 1 put    % either way we go to the next stage
  491.   pfbhdr type1readdata
  492.   1 index 0 get 16#80 eq {
  493.     (\n   **** Warning: Embedded Type1 font in PFB format is not valid PDF.)
  494.     pdfformaterror
  495.     DEBUG { (skipping PFB header) = flush } if
  496.     exch pop buffer 0 5 getinterval type1readdata exch
  497.     dup 4 get 256 mul 1 index 3 get add 256 mul
  498.     1 index 2 get add 256 mul 1 index 1 get add
  499.     DEBUG { (PFB segment length = ) print dup = } if
  500.     exch pop  % discard the string keeping the PFB segment length
  501.     2 copy ne {
  502.       (\n   **** Warning: Type 1 PFB segment length and Length 1 value do not match.)
  503.       pdfformaterror
  504.       exch     % keep the PFB length instead
  505.     } if
  506.     pop
  507.     buffer type1readdata    % go ahead and read a block
  508.   }
  509.   if    % if not PFB, return pfbhdr string (first char of file, usually %).
  510. } bdef
  511.  
  512. % Read the next block of the initial text portion.
  513. /type1read1 {        % <left> type1read1 <string> <left'>
  514.   DEBUG { (read1 ) print } if
  515.   dup 0 eq {
  516.     pop sectionstr 0 2 put
  517.     stream /Length2 oget
  518.             % Determine whether to hexify data for eexec.
  519.     dup 8 lt {
  520.       type1read2    % Hexify.
  521.     } {
  522.       DEBUG { (read2 ) print } if
  523.       pfbhdr 0 get 16#80 eq {
  524.         % eat 6 more bytes of PFB junk before proceeding
  525.     DEBUG { (skipping PFB header in segment 2) = flush } if
  526.     buffer 0 6 getinterval type1readdata exch
  527.         dup 5 get 256 mul 1 index 4 get add 256 mul
  528.     1 index 3 get add 256 mul 1 index 2 get add
  529.         DEBUG { (PFB segment length = ) print dup = } if
  530.     exch pop  % discard the string keeping the PFB segment length
  531.     2 copy ne {
  532.           (\n   **** Warning: Type 1 PFB segment length and Length 2 value do not match.)
  533.           pdfformaterror
  534.       dup =
  535.       exch         % keep the PFB length instead
  536.     } if
  537.       pop
  538.       } if
  539.       buffer2 type1readdata exch
  540.             % The check doesn't have to be 100% accurate:
  541.             % hexifying is always OK.
  542.       dup 0 8 getinterval 0 exch { or } forall
  543.       128 ge {
  544.     /hexify { } store
  545.     /buffer2 buffer def    % We don't need an intermediate buffer.
  546.       } if hexify exch
  547.     } ifelse
  548.   } {
  549.     buffer type1readdata
  550.   } ifelse
  551. } bdef
  552.  
  553. % Convert a string from binary to hex for eexec.
  554. % Free variables: buffer.
  555. /buf2hex {        % <string> buf2hex <hexstring>
  556.   buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
  557.   buffer (>) search pop exch pop exch pop
  558. } bdef
  559.  
  560. % Read the next block of the encrypted portion.
  561. /type1trailer
  562. (0000000000000000000000000000000000000000000000000000000000000000\n\
  563. 0000000000000000000000000000000000000000000000000000000000000000\n\
  564. 0000000000000000000000000000000000000000000000000000000000000000\n\
  565. 0000000000000000000000000000000000000000000000000000000000000000\n\
  566. 0000000000000000000000000000000000000000000000000000000000000000\n\
  567. 0000000000000000000000000000000000000000000000000000000000000000\n\
  568. 0000000000000000000000000000000000000000000000000000000000000000\n\
  569. 0000000000000000000000000000000000000000000000000000000000000000\n\
  570. cleartomark\n)
  571. readonly def
  572. /type1read2 {        % <left> type1read2 <string> <left'>
  573.   DEBUG { (read2 ) print } if
  574.    dup 0 eq
  575.     { pop sectionstr 0 3 put
  576.       stream /Length3 oget
  577.       dup 0 eq
  578.        { DEBUG { (trailer ) print } if
  579.      type1trailer exch
  580.        }
  581.        { 
  582.          pfbhdr 0 get 16#80 eq {
  583.            % eat 6 more bytes of PFB junk before proceeding
  584.        DEBUG { (skipping PFB header in segment 3) = flush } if
  585.        buffer 0 6 getinterval type1readdata exch
  586.            dup 5 get 256 mul 1 index 4 get add 256 mul
  587.        1 index 3 get add 256 mul 1 index 2 get add
  588.            DEBUG { (PFB segment length = ) print dup = } if
  589.        exch pop  % discard the string keeping the PFB segment length
  590.        2 copy ne {
  591.            (\n   **** Warning: Type 1 PFB segment length and Length 3 value do not match.)
  592.            pdfformaterror
  593.          exch     % keep the PFB length instead
  594.        } if
  595.        pop
  596.        (\n) pdfformaterror
  597.          } if
  598.          type1read3
  599.        }
  600.       ifelse
  601.     }
  602.     { buffer2 type1readdata exch hexify exch
  603.     }
  604.    ifelse
  605. } bdef
  606.  
  607. % Read the next block of the final text portion.
  608. % When finished, this procedure returns an empty string.
  609. /type1read3        % <left> type1read3 <string> <left'>
  610.  { DEBUG { (read3 ) print } if
  611.    buffer type1readdata
  612.  } bdef
  613.  
  614. % ---------------- Type 3 fonts ---------------- %
  615.  
  616. /.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
  617.  
  618. /buildType3 {        % <Type3-font-resource> buildType3 <font>
  619.   8 dict begin
  620.     /FontType 3 def
  621.     /Resources 1 index /Resources knownoget { oforce } { 0 dict } ifelse def
  622.     /FontBBox 1 index /FontBBox get cvx def
  623.     /FontMatrix 1 index /FontMatrix oget def
  624.     /CharProcs 1 index /CharProcs oget def
  625.     1 index /Widths knownoget {
  626.       /Widths exch def
  627.       /FirstChar 1 index /FirstChar oget def
  628.       /LastChar 1 index /LastChar oget def
  629.     } if
  630.     /FontName 1 index /Name get genfontname def
  631.     /Encoding .notdefEncoding 2 index getencoding def
  632.         % We have to define BuildChar rather than BuildGlyph:
  633.         % there is no PDF equivalent of glyphshow, and we need
  634.         % the character code to access the Widths.
  635.     /BuildChar {
  636.         % Stack: font charcode
  637.       1 index begin 3 dict begin
  638.       /Font 3 -1 roll def /CharCode 1 index def
  639.       % Make unknown characters map to /.notdef
  640.       Encoding exch get dup CharProcs exch known
  641.         { CharProcs exch oget }
  642.     { pop CharProcs /.notdef oget }
  643.       ifelse
  644.       PDFfile fileposition exch
  645.       false resolvestream
  646.         % Stack: filepos stream
  647.         % Don't let setgcolor set the color inside the BuildGlyph
  648.         % procedure, because this causes an /undefined error.
  649.       q null /FillColor gput null /StrokeColor gput
  650.       Font /Resources get exch pdfopdict .pdfruncontext
  651.       Q
  652.       PDFfile exch setfileposition
  653.       end end
  654.     } bdef
  655.     FontName currentdict end definefont exch pop
  656. } bdef
  657. /.adjustcharwidth {    % <wx> <wy> .adjustcharwidth <wx'> <wy'>
  658.   /Widths where {
  659.     begin
  660.     CharCode FirstChar ge CharCode LastChar le and {
  661.       exch pop Widths CharCode FirstChar sub get exch
  662.     } if end
  663.   } if
  664. } bdef
  665.  
  666. % ---------------- TrueType fonts ---------------- %
  667.  
  668. /TTfonts mark
  669.   /Arial /Helvetica
  670.   /Arial,Italic /Helvetica-Oblique
  671.   /Arial,Bold /Helvetica-Bold
  672.   /Arial,BoldItalic /Helvetica-BoldOblique
  673.   /CourierNew /Courier
  674.   /CourierNew,Bold /Courier-Bold
  675.   /TimesNewRoman /Times-Roman
  676.   /TimesNewRoman,Italic /Times-Italic
  677.   /TimesNewRoman,Bold /Times-Bold
  678.   /TimesNewRoman,BoldItalic /Times-BoldItalic
  679.   %
  680.   /ArialBlack,Italic /Arial-BlackItalic
  681.   /ArialNarrow,Bold /ArialNarrow-Bold
  682.   /ArialNarrow,BoldItalic /ArialNarrow-BoldItalic
  683.   /ArialNarrow,Italic /ArialNarrow-Italic
  684.   /BookAntiqua,Bold /BookAntiqua-Bold
  685.   /BookAntiqua,BoldItalic /BookAntiqua-BoldItalic
  686.   /BookAntiqua,Italic /BookAntiqua-Italic
  687.   /BookmanOldStyle,Bold /BookmanOldStyle-Bold
  688.   /BookmanOldStyle,BoldItalic /BookmanOldStyle-BoldItalic
  689.   /BookmanOldStyle,Italic /BookmanOldStyle-Italic
  690.   /CenturyGothic,Bold /CenturyGothic-Bold
  691.   /CenturyGothic,BoldItalic /CenturyGothic-BoldItalic
  692.   /CenturyGothic,Italic /CenturyGothic-Italic
  693.   /ComicSansMS,Bold /ComicSansMS-Bold
  694.   /CourierNew,Bold /CourierNewPS-BoldMT
  695.   /CourierNew,BoldItalic /CourierNewPS-BoldItalicMT
  696.   /CourierNew,Italic /CourierNewPS-ItalicMT
  697.   /FranklinGothicMedium,Italic /FranklinGothic-MediumItalic
  698.   /Garamond,Bold /Garamond-Bold
  699.   /Garamond,Italic /Garamond-Italic
  700.   /Georgia,Bold /Georgia-Bold
  701.   /Georgia,BoldItalic /Georgia-BoldItalic
  702.   /Georgia,Italic /Georgia-Italic
  703.   /Tahoma,Bold /Tahoma-Bold
  704.   /TrebuchetMS,Bold /TrebuchetMS-Bold
  705.   /TrebuchetMS,BoldItalic /Trebuchet-BoldItalic
  706.   /TrebuchetMS,Italic /TrebuchetMS-Italic
  707.   /Verdana,Bold /Verdana-Bold
  708.   /Verdana,BoldItalic /Verdana-BoldItalic
  709.   /Verdana,Italic /Verdana-Italic
  710. .dicttomark readonly def
  711.  
  712. /buildTrueType {    % <TrueType-font-resource> buildTrueType <font>
  713.   dup /BaseFont get
  714.   dup TTfonts exch .knownget {
  715.     exch pop
  716.         % Hack required by the PDF specification: if the
  717.         % font resource has Subtype = /TrueType but the actual
  718.         % (installed) font is not a TrueType font, ignore the
  719.         % Encoding in the font resource.  However, all current
  720.         % versions of Acrobat Reader have the 14 base TrueType
  721.         % fonts built in, so this produces incorrect output for
  722.         % badly designed PDF files that specify these file names
  723.         % with /Subtype = /TrueType but no embedded definition.
  724.         % Compensate for this by removing the /Subtype key when
  725.         % looking up the font.
  726.     exch dup length dict copy dup /Subtype null put exch
  727.   } if
  728.   pdffindfont    % findfont for PDF
  729.   % disable the auto-bold and auto-italic since it sometimes applies
  730.   % so an already bold or italic substitute font
  731.   %findpdffont    % findfont and auto-bold and/or auto-italic font for PDF
  732. } bdef
  733.  
  734. % Read an embedded TrueType font.
  735. /readtruetype {        % <font-resource> <stream-dict> readtruetype <font>
  736.         % This is much simpler than readtype1, because we don't
  737.         % have to deal with the tripartite .PFB format.
  738.   1 index exch
  739.   PDFfile fileposition 3 1 roll
  740.   true resolvestream readfontfilter
  741.         % Stack: filepos fontres stream
  742.   1 index /Subtype get /CIDFontType2 eq {
  743.     .loadttcidfont
  744.         % Stack: filepos fontres cidfont
  745.     1 index /CIDToGIDMap knownoget {
  746.       dup /Identity eq {
  747.     pop
  748.       } {
  749.     true resolvestream
  750.         % The following doesn't work for CIDToGIDMaps with more
  751.         % than 32K-1 entries.  We'll fix it later if necessary.
  752.         % Stack: filepos fontres font mapstream
  753.     dup 2 index /CIDCount oget 2 mul string readstring pop exch closefile
  754.     exch dup length 5 add dict .copydict
  755.     dup /FID undef
  756.     dup /CIDMap 4 -1 roll put
  757.     dup /CIDFontName get exch /CIDFont defineresource
  758.       } ifelse
  759.     } if
  760.   } {
  761.     null 2 index getencoding .loadpdfttfont
  762.   } ifelse
  763.   exch pop
  764.   PDFfile 3 -1 roll setfileposition
  765.         % Ignore both the Encoding and the Widths.
  766.   exch pop
  767. } bdef
  768.  
  769. % ---------------- Type 0 fonts ---------------- %
  770.  
  771. % Predefine the known CMaps, but only create them on demand.
  772. /knownCMaps mark
  773.   /Identity-H { /Identity-H 0 makeIdentityCMap }
  774.   /Identity-V { /Identity-V 1 makeIdentityCMap }
  775. .dicttomark def
  776.  
  777. /makeIdentityCMap {        % <cmapname> <wmode> .makeIdentityCMap -
  778.   .currentglobal true .setglobal 3 1 roll
  779.   /CIDInit /ProcSet findresource begin
  780.   12 dict begin
  781.     begincmap
  782.     /WMode exch def
  783.     /CMapName exch def
  784.     /CIDSystemInfo 3 dict dup begin
  785.       /Registry (Adobe) def
  786.       /Ordering (Identity) def
  787.       /Supplement 0 def
  788.     end def
  789.     %/CMapName (see above)
  790.     /CMapVersion 1 def
  791.     /CMapType 1 def
  792.     %WMode (see above)
  793.     % The PDF documentation says that these CMaps map CIDs
  794.     % "1 to 65,536".  This is a misprint for 0 to 65,535.
  795.     1 begincodespacerange
  796.     % <0001> <00ff>  <0100> <ffff>
  797.       <0000> <ffff>
  798.     endcodespacerange
  799.     1 begincidrange
  800.     % <0001> <00ff> 1   <0100> <ffff> 256
  801.       <0000> <ffff> 0
  802.     endcidrange
  803.     endcmap
  804.     CMapName currentdict /CMap defineresource
  805.     knownCMaps CMapName 2 index put
  806.   end        % CMap
  807.   end        % CIDInit ProcSet
  808.   exch .setglobal
  809. } bdef
  810.  
  811. /buildType0 {        % <Type0-font-resource> buildType0 <font>
  812.   dup /BaseFont get    % FontName
  813.   1 index /Encoding oget
  814.   dup type /nametype eq {
  815.     dup /CMap resourcestatus {
  816.     pop pop /CMap findresource
  817.     } {
  818.     knownCMaps 1 index .knownget
  819.       { exch pop exec } { /undefined signalerror } ifelse
  820.     } ifelse
  821.   } {
  822.     PDFfile fileposition exch
  823.     dup /CMapName get exch true resolvestream cvx exec
  824.     /CMap findresource
  825.     exch PDFfile exch setfileposition
  826.   } ifelse        % CMap
  827.   [
  828.     3 index /DescendantFonts oget { exec resourcefont } forall
  829.   ]            % subfonts
  830.   composefont
  831.         % Stack: fontres font
  832.   1 index /FontMatrix knownoget {
  833.     dup aload pop true {0 0 1 0 0 1} {3 -1 roll eq and} forall {
  834.       1 index exch makefont exch /FontName get exch definefont
  835.     } {
  836.       pop
  837.     } ifelse
  838.   } if exch pop
  839. } bdef
  840.  
  841. % ---------------- CIDFontType0/2 fonts ---------------- %
  842.  
  843. % Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2
  844. % arrays and using a (currently very inefficient) CDevProc.
  845. % For detail, refer "PDF Reference" third edition, p. 337,
  846. % "5.6.3 CIDFonts" and table "Entries in a CIDFont dictionary".
  847.  
  848. /.pdfDefaultDW  1000 def
  849. /.pdfDefaultDW2 [ 880 -1000 ] def
  850.  
  851. /addCIDmetrics {    % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict>
  852.   dup length 5 add dict .copydict
  853.   dup /FID undef
  854.   dup /UniqueID undef
  855.   dup /XUID undef
  856.     % Insert the widths into the font.
  857.  
  858.     % Stack: pdfresource newfont
  859.  
  860.   1 index /DW .knownget {
  861.     1 index /DW 3 -1 roll put
  862.     } {
  863.     dup /DW .pdfDefaultDW put
  864.     } ifelse
  865.  
  866.  
  867.   1 index /W .knownget {
  868.     dup 2 index /W 3 -1 roll put
  869.     .pdfMakeInternalW 1 index /.internalW 3 -1 roll put
  870.   } if
  871.  
  872.  
  873.   1 index /DW2 .knownget {
  874.     1 index /DW2 3 -1 roll put
  875.   } {
  876.     dup /DW2 .pdfDefaultDW2 put
  877.   } ifelse
  878.  
  879.  
  880.   1 index /W2 .knownget {
  881.     dup 2 index /W2 3 -1 roll put
  882.     .pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put
  883.   } if
  884.  
  885.  
  886.   dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put
  887.   exch pop
  888. } bdef
  889.  
  890. /.pdfMakeInternalMTXArray { % <mtx_array> <item_size> .pdfConvertInternalW <mtx_array'>
  891.  
  892.   % convert /W or /W2 to internal expression
  893.   %
  894.   %   mtx_array: original /W or /W2 array
  895.   %   item_size: number of metrics values per CID
  896.   %
  897.   %   for detail of the metrics list format in PDF,
  898.   %   refer PDF Ref. p.317 "Glyph Metrics in CIDFonts".
  899.   % 
  900.   %   format of single entry in internal expression
  901.   %
  902.   %     [
  903.   %       [cid_begin cid_end]
  904.   %       value_is_varied (bool)
  905.   %       [ [values for cid_begin...]
  906.   %         [values for cid_begin + 1]
  907.   %         ... ]
  908.   %     ]
  909.   %
  910.  
  911.   7 dict
  912.   begin
  913.     /itemSize exch def
  914.     /M exch def            % original /W or /W2
  915.     /Msize M length def
  916.     /Mi { M i get } def        % W[i]
  917.     /Mi1 { M i 1 add get } def    % W[i + 1]
  918.     /putMTXEntry <<
  919.       /arraytype   {
  920.          [
  921.            [Mi Mi Mi1 length add 1 sub]
  922.            true
  923.            [
  924.              0 itemSize Mi1 length 1 sub {
  925.                [ exch 1 1 index itemSize add 1 sub { Mi1 exch get } for ]
  926.              } for
  927.            ]
  928.          ]
  929.          /i i 2 add def
  930.       }
  931.       /integertype {
  932.          [
  933.            [Mi Mi1]
  934.            false
  935.            [[ i 2 add 1 i 1 add itemSize add { M exch get } for ]]
  936.          ]
  937.          /i i 3 add def
  938.       }
  939.     >> def
  940.  
  941.     /i 0 def
  942.  
  943.     [ { putMTXEntry Mi1 type get exec i Msize ge { exit } if } loop ]
  944.   end
  945. } def
  946.  
  947. /.pdfMakeInternalW  { dup length 0 gt { 1 .pdfMakeInternalMTXArray } if } def
  948. /.pdfMakeInternalW2 { dup length 0 gt { 3 .pdfMakeInternalMTXArray } if } def
  949.  
  950. /.pdfGetMTXByCID { % <internalMTXArray> <cid>
  951.                    %     .pdfGetMTXByCID
  952.                    %         { <MTXEntry> true | false }
  953.  
  954.   % get values for given CID from internal format of /W or /W2
  955.  
  956.   exch
  957.   {
  958.     {
  959.       dup 0 get {} forall      % Stack: <cid> <entry> <cid_0> <cid_1>
  960.       3 index lt { pop pop false exit } if
  961.       2 index exch sub dup 0 lt { pop pop false exit } if
  962.       1 index 1 get not { pop 0 } if
  963.       exch 2 get exch get true exit
  964.     } loop
  965.     { exit } if
  966.   } forall
  967.   dup type /arraytype eq { exch pop true } { pop false } ifelse
  968. } def
  969.  
  970.  
  971. % Apply the [D]W[2] metrics to a character before displaying.
  972. /CIDWProc {        % <w0x> <w0y> <llx> <lly> <urx> <ury>
  973.             %   <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
  974.             %   <w0x'> ... <vy'>
  975.  
  976.   begin % push <font> to currentdict
  977.     % <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now
  978.     5 1 roll pop pop pop pop
  979.  
  980.     {
  981.       currentdict /DW .knownget not {   % no DW
  982.         .pdfDefaultDW exit              % replace <w0x> by defaultDW
  983.       } if
  984.  
  985.       currentdict /.internalW .knownget not {    % no W
  986.         exit                            % use already-stacked DW
  987.       } if
  988.  
  989.       dup length 0 eq {                 % W is null array
  990.         pop                             % discard unusable W
  991.         exit                            % use already-stacked DW
  992.       } if
  993.  
  994.       % W is finite array, try to get W_cid
  995.       2 index .pdfGetMTXByCID {           % got W, discard DW
  996.         exch pop {} forall
  997.         exit
  998.       } if
  999.  
  1000.       exit
  1001.     } loop
  1002.  
  1003.     1000 div                    % <w0x'> (normalized W)
  1004.     0                           % <w0y'>
  1005.  
  1006.     % Stack: <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'>
  1007.     9 -2 roll pop pop           % discard <w0x> <w0y>
  1008.     7  2 roll                   % put <w0x'> <w0y'>
  1009.  
  1010.     % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <cid>
  1011.     0                           % <w1x'>
  1012.     exch                        % put <w1x'>
  1013.  
  1014.     % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <cid>
  1015.     {
  1016.       currentdict /DW2 .knownget not {  % no DW2, use defaultDW2
  1017.         .pdfDefaultDW2 exit
  1018.       } if
  1019.  
  1020.       currentdict /.internalW2 .knownget not {   % has DW2, no W2
  1021.         exit                            % use already-stacked DW2
  1022.       } if
  1023.  
  1024.       dup length 0 eq {                 % W2 is null array
  1025.         pop                             % discard unusable W2
  1026.         exit                            % use already-stacked DW2
  1027.       } if
  1028.  
  1029.       2 index .pdfGetMTXByCID {        % got W2_cid, discard DW2
  1030.         exch pop
  1031.         exit
  1032.       } if
  1033.  
  1034.       % could not get W2_cid
  1035.       exit
  1036.  
  1037.     } loop
  1038.  
  1039.     exch pop                            % discard <cid>
  1040.  
  1041.  
  1042.     % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] }
  1043.     dup length 2 eq {                   % this is DW2
  1044.       {1000 div} forall exch
  1045.       4 index 7 index add 2 div         % <vx'> = (<urx> + <llx>) / 2
  1046.       exch
  1047.     }{                                  % assume W2
  1048.       {1000 div} forall
  1049.     } ifelse
  1050.   end                                   % recover currentdict
  1051.  
  1052. } def
  1053.  
  1054.  
  1055.  
  1056. %----------------------------------------------------------------
  1057.  
  1058. % <string> <match> tailmatch ==> <pre> true
  1059. %                            ==> <string> false
  1060. /tailmatch {
  1061.   2 copy length 1 index length .min
  1062.   dup 2 index length exch sub exch getinterval
  1063.   1 index eq {
  1064.     length 1 index length exch sub
  1065.     0 exch getinterval true
  1066.   } {
  1067.     pop false
  1068.   } ifelse
  1069. } bind def
  1070.  
  1071. /makeboldcidfont {
  1072.   16 dict begin
  1073.     /strokewidth exch def
  1074.     /basecidfont exch def
  1075.     /FontMatrix [ 1 0 0 1 0 0 ] def
  1076.  
  1077.     /CIDFontName /.boldfont def
  1078.     /CIDFontType 1 def
  1079.  
  1080.     /basefont-H /.basefont-H /Identity-H [ basecidfont ] composefont def
  1081.     /basefont-V /.basefont-V /Identity-V [ basecidfont ] composefont def
  1082.  
  1083.     /CIDSystemInfo dup basecidfont exch get def
  1084.     /FontBBox [ basecidfont /FontBBox get cvx exec
  1085.       4 2 roll basecidfont /FontMatrix get transform
  1086.       4 2 roll basecidfont /FontMatrix get transform
  1087.     ] def
  1088.  
  1089.     /tmpstr 2 string def
  1090.     /BuildGlyph {
  1091.       gsave
  1092.       exch begin
  1093.         dup 256 idiv tmpstr exch 0 exch put
  1094.         256 mod tmpstr exch 1 exch put
  1095.         rootfont /WMode known { rootfont /WMode get 1 eq } { false } ifelse
  1096.         { basefont-V } { basefont-H } ifelse setfont
  1097.         strokewidth setlinewidth
  1098.         1 setlinejoin
  1099.         newpath
  1100.         0 0 moveto tmpstr false charpath stroke
  1101.         0 0 moveto tmpstr show
  1102.         currentpoint setcharwidth
  1103.       end
  1104.       grestore
  1105.     } bind def
  1106.  
  1107.    currentdict
  1108.   end
  1109.   dup /CIDFontName get exch /CIDFont defineresource
  1110. } bind def
  1111.  
  1112. % <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font>
  1113. %   CIDFont-resource is not modified.
  1114. /findCIDFont {
  1115.   {
  1116.     dup /CIDFont resourcestatus {
  1117.       pop pop /CIDFont findresource
  1118.       exit
  1119.     } if
  1120.  
  1121.     dup dup length string cvs
  1122.     (,Bold) tailmatch {
  1123.       exch pop
  1124.       cvn findCIDFont 0.03 makeboldcidfont
  1125.       exit
  1126.     } if
  1127.     (,Italic) tailmatch {
  1128.       exch pop
  1129.       cvn findCIDFont
  1130.       [ 1 0 0.3 1 0 0 ] makefont
  1131.       exit
  1132.     } if
  1133.     (,BoldItalic) tailmatch {
  1134.       exch pop
  1135.       cvn findCIDFont 0.03 makeboldcidfont
  1136.       [ 1 0 0.3 1 0 0 ] makefont
  1137.       exit
  1138.     } if
  1139.     pop
  1140.  
  1141.     1 index /CIDSystemInfo get begin Registry (-) Ordering end
  1142.     concatstrings concatstrings
  1143.     cvn
  1144.     QUIET not {
  1145.       (Substituting ) print dup ==only
  1146.       ( for ) print 1 index ==only (.\n) print
  1147.     } if
  1148.     exch pop
  1149.     /CIDFont findresource
  1150.     exit
  1151.   } loop
  1152. } bdef
  1153.  
  1154. /buildCIDType0 {    % <CIDFontType0-font-resource> buildCIDType0 <font>
  1155.   dup /BaseFont get exch 1 index findCIDFont
  1156.   addCIDmetrics /CIDFont defineresource
  1157. } bdef
  1158.  
  1159. /buildCIDType2 {    % <CIDFontType2-font-resource> buildCIDType2 <font>
  1160.   dup /BaseFont get exch 1 index findCIDFont
  1161.   addCIDmetrics /CIDFont defineresource
  1162. } bdef
  1163.  
  1164. % ---------------- Other embedded fonts ---------------- %
  1165.  
  1166. /fontloadprocs mark
  1167.   /Type1C /readType1C cvx
  1168.   /CIDFontType0C /readCIDFontType0C cvx
  1169. .dicttomark readonly def
  1170.  
  1171. % Read an embedded compressed font.
  1172. /readType1C {        % <font-resource> <stream-dict> readType1C <font>
  1173.   1 index exch
  1174.   PDFfile fileposition 3 1 roll
  1175.   dup true resolvestream dup readfontfilter
  1176.         % Stack: pos resource streamdict stream filter
  1177.   3 index /FontDescriptor oget /FontName oget
  1178.   1 index FRD
  1179.   closefile closefile pop
  1180.   PDFfile 3 -1 roll setfileposition
  1181.   /FontDescriptor oget /FontName oget findfont
  1182.   adjustfont
  1183. } bdef
  1184.  
  1185. % Read an embedded CFF CIDFont.
  1186. /readCIDFontType0C {  % <font-resource> <stream-dict> readCIDFontType0C <font>
  1187.   PDFfile fileposition 3 1 roll
  1188.   dup true resolvestream dup readfontfilter
  1189.         % Stack: pos resource streamdict stream filter
  1190.   3 index /FontDescriptor oget /FontName oget
  1191.   1 index FRD
  1192.   closefile closefile pop
  1193.   PDFfile 3 -1 roll setfileposition
  1194.         % Some broken Adobe software produces PDF files in which
  1195.         % the FontName of the CFF font and the FontName in the
  1196.         % FontDescriptor don't match the BaseFont in the font.
  1197.         % Use the FontName, rather than the BaseFont, here.
  1198.   dup /FontDescriptor oget /FontName oget /CIDFont findresource
  1199.   addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
  1200. } bdef
  1201.  
  1202. % ---------------- Font lookup ---------------- %
  1203.  
  1204. /fonttypeprocs mark        % <font-resource> -proc- <font>
  1205.   /Type0 /buildType0 cvx
  1206.   /Type1 /buildType1 cvx
  1207.   /MMType1 1 index
  1208.   /Type3 /buildType3 cvx
  1209.   /TrueType /buildTrueType cvx
  1210.   /CIDFontType0 /buildCIDType0 cvx
  1211.   /CIDFontType2 /buildCIDType2 cvx
  1212. .dicttomark readonly def
  1213.  
  1214. /resourcefont            % <font-resource> resourcefont <font>
  1215.  { dup /PSFont .knownget
  1216.     { /FID .knownget { type /fonttype eq } { false } ifelse }
  1217.     { false }
  1218.    ifelse
  1219.     { /PSFont get
  1220.     }
  1221.     { dup dup /FontDescriptor knownoget
  1222.        {    % Stack: font-res font-res font-desc
  1223.      dup /FontFile knownoget
  1224.       { exch pop readtype1 true }
  1225.       { dup /FontFile2 knownoget
  1226.          { exch pop readtruetype true }
  1227.          { /FontFile3 knownoget
  1228.         { dup /Subtype get fontloadprocs exch get exec true }
  1229.         { false }
  1230.            ifelse
  1231.          }
  1232.         ifelse
  1233.       }
  1234.      ifelse
  1235.        }
  1236.        { false }
  1237.       ifelse
  1238.         % Stack: font-res font-res false
  1239.         %  -or-: font-res font true
  1240.       not
  1241.        { dup /Subtype get fonttypeprocs exch get exec }
  1242.       if
  1243.       2 copy /PSFont exch put
  1244.       exch pop
  1245.     }
  1246.    ifelse
  1247.  } bdef
  1248.  
  1249. drawopdict begin
  1250.   /d0 {
  1251.     .adjustcharwidth setcharwidth
  1252.   } bdef
  1253.   /d1 {
  1254.     6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
  1255.   } bdef
  1256.   /Tf {
  1257.     1 index Page /Font rget not { 1 index /invalidfont signalerror } if
  1258.     resourcefont exch Tf pop
  1259.   } bdef
  1260. end
  1261.  
  1262. end            % pdfdict
  1263. end            % GS_PDF_ProcSet
  1264. .setglobal
  1265.